package cn.jane.rpc.api;

import cn.jane.rpc.api.spi.ServiceSupport;

import java.io.Closeable;
import java.net.URI;
import java.util.Collection;

/**
 * RPC 框架对外提供服务的接口
 */
public interface RpcAccessPoint extends Closeable {

    /**
     * 客户端获取远程服务
     *
     * @param serviceUri   远程服务的地址
     * @param serviceClass 服务接口的字节码对象
     * @param <T>          服务接口的类型
     * @return 远程服务对象
     */
    <T> T getRemoteService(URI serviceUri, Class<T> serviceClass);

    /**
     * 服务端注册远程服务
     *
     * @param service      远程服务的实现对象
     * @param serviceClass 服务接口的字节码对象
     * @param <T>          服务接口的类型
     * @return 调用远程服务的 URI
     */
    <T> URI addServiceProvider(T service, Class<T> serviceClass);

    /**
     * 获取注册中心
     *
     * @param nameServiceUri 待获取注册中心的 URI
     * @return 注册中心对象
     */
    default NameService getNameService(URI nameServiceUri) {
        Collection<NameService> nameServices = ServiceSupport.loadAll("nameService", NameService.class);
        for (NameService nameService : nameServices) {
            if (nameService.supportedSchemes().contains(nameServiceUri.getScheme())) {
                nameService.connect(nameServiceUri);
                return nameService;
            }
        }
        return null;
    }

    /**
     * 服务端启动 RPC 框架，监听接口，开始提供远程调用服务
     *
     * @return 服务实例，用于程序停止时安全关闭服务
     * @throws Exception 服务端启动时可能会抛出的异常
     */
    Closeable startServer() throws Exception;
}
